package com.fingard.dsp.bank.directbank.citic02;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IContract;
import com.fingard.dsp.bank.reqrespobj.contract.*;
import com.fingard.dsp.bank.reqrespobj.contract.detail.RetAtsContractDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Date;

/**
 * 中信银行委托代收系统签约
 * 
 * 参考文档：中信银行直连委托代收系统报文接口及文件数据格式规范v2.6.2.doc
 * 
 * @author Cruise
 * @date 2019/4/30
 */
public class CITIC02Contract extends CITIC02Base implements IContract {
	/**
	 * 开发接口：
	 * 1. 2.7	实时短信签约（交易码SSQY001）
	 * 2. 2.8	实时短信签约/解约验证码验证（交易码DXYZ001）
	 */
	@Override
	public RetAtsContract contract(ReqContract p_req) throws Exception {
		RetAtsContract retAts = new RetAtsContract(p_req.reqHeader);
		RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
		tmpRetDetail.reqSeqID = p_req.contractDetail.askNumber;
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req.contractDetail.recAct, "");
			if(actItem ==null) {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号[" + p_req.contractDetail.recAct + "]商户配置信息!1";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\"?>");
			xmlWriter.writeStartElement("ROOT");
			
			if ("01".equals(p_req.contractDetail.step)) {
				xmlWriter.writeElementString("trancode", "SSQY001");
                xmlWriter.writeElementString("sndseqno", p_req.contractDetail.askNumber);
                xmlWriter.writeElementString("mccprtcno", actItem.appId);
                xmlWriter.writeElementString("mrchname", actItem.userCode);
                xmlWriter.writeElementString("mrchtype", "0401");// 0401	金融服务类-保险费
                xmlWriter.writeElementString("payname", p_req.contractDetail.payName);
                xmlWriter.writeElementString("payacc", p_req.contractDetail.payAct);
                xmlWriter.writeElementString("phone", p_req.contractDetail.cellPhone);
                xmlWriter.writeElementString("idtype", convertCertTypeToBank(p_req.contractDetail.certType));
                xmlWriter.writeElementString("idno", p_req.contractDetail.certNum);
				String deadLine = "";
				String singleLimit = "";
				String dayAmtLimit = "";
				String monthAmtLimit = "";
                if (getBankConfig().getValueAsBool("contractKeySwifch")){
					deadLine = getBankConfig().getMapValueByKey("contractKeyMapping", "deadLine");
					singleLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "singleLimit");
					dayAmtLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "dayAmtLimit");
					monthAmtLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "monthAmtLimit");
				}else{
					deadLine = p_req.contractDetail.deadLine;
					if (StringHelper.isNullOrEmpty(deadLine)) {
						deadLine = getBankConfig().getMapValueByKey("contractKeyMapping", "deadLine");
						if (StringHelper.isNullOrEmpty(deadLine)) {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = "缺失配置节点'deadLine'或值为空!";
							retAts.writeRetDetail(tmpRetDetail);
							return retAts;
						}
					}
					singleLimit = p_req.contractDetail.singleLimit;
					if (StringHelper.isNullOrEmpty(singleLimit)) {
						singleLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "singleLimit");
						if (StringHelper.isNullOrEmpty(singleLimit)) {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = "缺失配置节点'singleLimit'或值为空!";
							retAts.writeRetDetail(tmpRetDetail);
							return retAts;
						}
					}
					dayAmtLimit = p_req.contractDetail.dayAmtLimit;
					if (StringHelper.isNullOrEmpty(dayAmtLimit)) {
						dayAmtLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "dayAmtLimit");
						if (StringHelper.isNullOrEmpty(dayAmtLimit)) {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = "缺失配置节点'dayAmtLimit'或值为空!";
							retAts.writeRetDetail(tmpRetDetail);
							return retAts;
						}
					}
					monthAmtLimit = p_req.contractDetail.monthAmtLimit;
					if (StringHelper.isNullOrEmpty(monthAmtLimit)) {
						monthAmtLimit = getBankConfig().getMapValueByKey("contractKeyMapping", "monthAmtLimit");
						if (StringHelper.isNullOrEmpty(monthAmtLimit)) {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = "缺失配置节点'monthAmtLimit'或值为空!";
							retAts.writeRetDetail(tmpRetDetail);
							return retAts;
						}
					}
				}
				xmlWriter.writeElementString("duedt", Format.Date10Format.format(Format.Date8Format.parse(deadLine)));
				xmlWriter.writeElementString("sigllimtamt", singleLimit);
				xmlWriter.writeElementString("daylimtamt", dayAmtLimit);
				xmlWriter.writeElementString("mothlimtamt", monthAmtLimit);
	            xmlWriter.writeEndDocument();
			} else if ("02".equals(p_req.contractDetail.step)) {
				xmlWriter.writeElementString("trancode", "DXYZ001");
                xmlWriter.writeElementString("sndseqno", getQryTransID());
                xmlWriter.writeElementString("osndseqno", p_req.contractDetail.askNumber);
                xmlWriter.writeElementString("mccprtcno", actItem.appId);
                xmlWriter.writeElementString("code", p_req.contractDetail.smsCode);
                xmlWriter.writeElementString("flag", "00");
                xmlWriter.writeEndDocument();
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未能识别的step：" + p_req.contractDetail.step;
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			
			StringBuilder sbContent=new StringBuilder();
            //报文长度（8）+地区码（4）+业务种类（6）+委托单位（15）+业务单位（15）+渠道号（8）+外部交易码（15） 
			String area=getBankConfig().getValueAsString("area");
			String businessTypes=getBankConfig().getValueAsString("businessTypes");
			String entrustmentUnit=getBankConfig().getValueAsString("entrustmentUnit");
			String businessUnit=getBankConfig().getValueAsString("businessUnit");
			String channelNumber=getBankConfig().getValueAsString("channelNumber");
			sbContent.append(String.format("%-4s", area));//地区码
			sbContent.append(String.format("%-6s", businessTypes));//业务种类
			sbContent.append(String.format("%-15s", entrustmentUnit));//委托单位
			sbContent.append(String.format("%-15s", businessUnit));//业务单位
			sbContent.append(String.format("%-8s", channelNumber));//渠道号
			if ("01".equals(p_req.contractDetail.step)) {
				sbContent.append(String.format("%-15s", "SSQY001"));//外部交易码
			} else {
				sbContent.append(String.format("%-15s", "DXYZ001"));//外部交易码
			}
            String tmpStrPlain = xmlWriter.toXmlString();
            String result=sbContent.toString();
            String sendMessage=result+tmpStrPlain;
            String[] tmpRetStr = sendToBank(sendMessage);
			if(tmpRetStr[0].length() == 0) {
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
				if (tmpBkReader != null) {
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = tmpBkReader.getFirstText("/ROOT/respinfo");
					String transStatus = tmpBkReader.getFirstText("/ROOT/stat");
					if("01".equals(p_req.contractDetail.step)) {
						if ("05".equals(transStatus)) {
							RetAtsContract req = qryContract(p_req);
							if("0".equals(req.retDetail.respCode)){
								tmpRetDetail.authCode=req.retDetail.authCode;
							}else {
								tmpRetDetail.respCode = "-1";
								tmpRetDetail.respInfo = "签约失败";
							}
						}else if("00".equals(transStatus)){

						}else {
							tmpRetDetail.respCode = "-1";
						}
						tmpRetDetail.signConfirmType = "2";
						tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", "01"+transStatus);
					} else {
						if ("00".equals(transStatus) || "06".equals(transStatus)) {
							RetAtsContract req = qryContract(p_req);
							if("0".equals(req.retDetail.respCode)){
								tmpRetDetail.authCode=req.retDetail.authCode;
								tmpRetDetail.signState = ContractState.SUCCESS;
							}else {
								tmpRetDetail.respCode = "-1";
								tmpRetDetail.respInfo = "签约中";
								tmpRetDetail.signState = ContractState.SIGNING;
							}
						} else {
							tmpRetDetail.signState = ContractState.FAIL;
						}
						tmpRetDetail.unifiedCode = getBankConfig().getMapValueByKey("contractMapping", "02"+transStatus);
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpSbMsg.toString();
				}
			} else {
				tmpRetDetail.respCode = "-1"; 
				tmpRetDetail.respInfo = tmpRetStr[1];
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

    @Override
    public RetAtsContract upContract(ReqContract p_req) throws Exception {
        return null;
    }

    /**
	 * 开发接口：
	 * 1. 2.10	客户签约状态查询（交易码QYCX001）
	 */
	@Override
	public RetAtsContract qryContract(ReqContract p_reqQry) throws Exception {
		RetAtsContract retAts = new RetAtsContract(p_reqQry.reqHeader);
		RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
		tmpRetDetail.reqSeqID = p_reqQry.contractDetail.askNumber;
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQry.contractDetail.recAct, "");
			if(actItem ==null) {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号[" + p_reqQry.contractDetail.recAct + "]商户配置信息!";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\"?>");
			xmlWriter.writeStartElement("ROOT");
			xmlWriter.writeElementString("trancode", "QYCX001");
            xmlWriter.writeElementString("sndseqno", getQryTransID());
            xmlWriter.writeElementString("mccprtcno", actItem.appId);
            xmlWriter.writeElementString("payname", p_reqQry.contractDetail.payName);
            xmlWriter.writeElementString("payacc", p_reqQry.contractDetail.payAct);
            xmlWriter.writeElementString("phone", p_reqQry.contractDetail.cellPhone);
            xmlWriter.writeElementString("idtype", convertCertTypeToBank(p_reqQry.contractDetail.certType));
            xmlWriter.writeElementString("idno", p_reqQry.contractDetail.certNum);
            xmlWriter.writeEndDocument();
			
			StringBuilder sbContent=new StringBuilder();
            //报文长度（8）+地区码（4）+业务种类（6）+委托单位（15）+业务单位（15）+渠道号（8）+外部交易码（15） 
			String area=getBankConfig().getValueAsString("area");
			String businessTypes=getBankConfig().getValueAsString("businessTypes");
			String entrustmentUnit=getBankConfig().getValueAsString("entrustmentUnit");
			String businessUnit=getBankConfig().getValueAsString("businessUnit");
			String channelNumber=getBankConfig().getValueAsString("channelNumber");
			sbContent.append(String.format("%-4s", area));//地区码
			sbContent.append(String.format("%-6s", businessTypes));//业务种类
			sbContent.append(String.format("%-15s", entrustmentUnit));//委托单位
			sbContent.append(String.format("%-15s", businessUnit));//业务单位
			sbContent.append(String.format("%-8s", channelNumber));//渠道号
			sbContent.append(String.format("%-15s", "QYCX001"));//外部交易码
            
            String tmpStrPlain = xmlWriter.toXmlString();
            String result=sbContent.toString();
            String sendMessage=result+tmpStrPlain;
            
            /*String ownKeyPassword = getBankConfig().getMapValueByKey("merchantInfo", "ownKeyPassword");
            String ownKeyStorePath = getBankConfig().getMapValueByKey("merchantInfo", "ownKeyStorePath");
            String ownCertFilePath = getBankConfig().getMapValueByKey("merchantInfo", "ownCertFilePath");
            String oppCertFilePath = getBankConfig().getMapValueByKey("merchantInfo", "oppCertFilePath");*/
            
            String[] tmpRetStr = sendToBank(sendMessage);
			if(tmpRetStr[0].length() == 0) {
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
				if (tmpBkReader != null) {
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = tmpBkReader.getFirstText("/ROOT/respinfo");

					String transStatus = tmpBkReader.getFirstText("/ROOT/stat");
					if (StringHelper.hasAnyChar(transStatus)) {
						if ("00".equals(transStatus)) {
							tmpRetDetail.signState = ContractState.SUCCESS;
						} else if ("01".equals(transStatus)) {
							tmpRetDetail.signState = ContractState.UNSIGNED;
						} else {
							tmpRetDetail.signState = ContractState.FAIL;
						}
						tmpRetDetail.payAct = p_reqQry.contractDetail.payAct;
						tmpRetDetail.payName = p_reqQry.contractDetail.payName;
						tmpRetDetail.certType = p_reqQry.contractDetail.certType;
						tmpRetDetail.certNum = p_reqQry.contractDetail.certNum;
						tmpRetDetail.cellPhone = p_reqQry.contractDetail.cellPhone;
						tmpRetDetail.authCode = tmpBkReader.getFirstText("/ROOT/protocolno");
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpBkReader.getFirstText("/ROOT/retcode") + "+" + tmpBkReader.getFirstText("/ROOT/retmsg");
					}
					tmpRetDetail.signConfirmType = "2";
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpSbMsg.toString();
				}
			} else {
				tmpRetDetail.respCode = "-1"; 
				tmpRetDetail.respInfo = tmpRetStr[1];
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@Override
	public RetAtsQryBatContract qryBatContract(ReqQryBatContract p_reqQry) throws Exception {
        RetAtsQryBatContract retAts = new RetAtsQryBatContract(p_reqQry.reqHeader);

        try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQry.ownAct, "");
			if(actItem ==null) {
				retAts.respCode = "-1";
				retAts.respInfo = "未找到账号[" + p_reqQry.ownAct + "]商户配置信息!";
				return retAts;
			}
            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\"?>");
            xmlWriter.writeStartElement("ROOT");
            xmlWriter.writeElementString("trancode", "QYCX002");
            xmlWriter.writeElementString("sndseqno", getQryTransID());
            xmlWriter.writeElementString("cxtype", "2");
            xmlWriter.writeElementString("std400date", Format.Date8Format.format(new Date()));
            xmlWriter.writeElementString("startnum", "1");
            xmlWriter.writeElementString("std400acur", "200");
            xmlWriter.writeElementString("mccprtcno", actItem.appId);

            while (p_reqQry.readRecord()) {
                xmlWriter.writeStartElement("LIST");
                xmlWriter.writeElementString("payname", p_reqQry.contractDetail.payName);
                xmlWriter.writeElementString("payacc", p_reqQry.contractDetail.payAct);
                xmlWriter.writeElementString("phone", p_reqQry.contractDetail.cellPhone);
                xmlWriter.writeElementString("idtype", convertCertTypeToBank(p_reqQry.contractDetail.certType));
                xmlWriter.writeElementString("idno", p_reqQry.contractDetail.certNum);
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndDocument();
            StringBuilder sbContent=new StringBuilder();
            //报文长度（8）+地区码（4）+业务种类（6）+委托单位（15）+业务单位（15）+渠道号（8）+外部交易码（15）
            String area=getBankConfig().getValueAsString("area");
            String businessTypes=getBankConfig().getValueAsString("businessTypes");
            String entrustmentUnit=getBankConfig().getValueAsString("entrustmentUnit");
            String businessUnit=getBankConfig().getValueAsString("businessUnit");
            String channelNumber=getBankConfig().getValueAsString("channelNumber");
            sbContent.append(String.format("%-4s", area));//地区码
            sbContent.append(String.format("%-6s", businessTypes));//业务种类
            sbContent.append(String.format("%-15s", entrustmentUnit));//委托单位
            sbContent.append(String.format("%-15s", businessUnit));//业务单位
            sbContent.append(String.format("%-8s", channelNumber));//渠道号
            sbContent.append(String.format("%-15s", "QYCX002"));//外部交易码
            String tmpStrPlain = xmlWriter.toXmlString();
            String result=sbContent.toString();
            String sendMessage=result+tmpStrPlain;
            WriteBankLogLn2("发送银行请求数据明文:\r\n" + sendMessage);
            String[] tmpStrRet = sendToBank(sendMessage);
            if(tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRespCode = tmpBkReader.getFirstText("/ROOT/respcode");
                    if ("AAAAAAA".equalsIgnoreCase(tmpRespCode)) {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpBkReader.getFirstText("/ROOT/respinfo");
                        while(tmpBkReader.read("/ROOT/LIST")) {
                            RetAtsContractDetail tmpRetDetail = new RetAtsContractDetail();
                            String transStatus = tmpBkReader.readedXElement.getSingleText("stat");
                            if ("00".equals(transStatus)) {
                                tmpRetDetail.signState = ContractState.SUCCESS;
                            } else if ("01".equals(transStatus)) {
                                tmpRetDetail.signState = ContractState.UNSIGNED;
                            } else {
                                tmpRetDetail.signState = ContractState.FAIL;
                            }
                            tmpRetDetail.signMsg = tmpBkReader.readedXElement.getSingleText("respinfo");
                            tmpRetDetail.authCode = tmpBkReader.readedXElement.getSingleText("protocolno");
                            tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("payacc");
                            tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("payname");
                            tmpRetDetail.cellPhone = tmpBkReader.readedXElement.getSingleText("phone");
                            tmpRetDetail.certType = convertCertTypeToBank(tmpBkReader.readedXElement.getSingleText("idtype"));
                            tmpRetDetail.certNum = tmpBkReader.readedXElement.getSingleText("idno");
                            tmpRetDetail.signConfirmType = "2";
                            retAts.writeRetDetail(tmpRetDetail);
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpBkReader.getFirstText("/ROOT/respinfo");
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeEnd();
        return retAts;
	}
}